/****************************************************************************
 * Copyright (C) 2012 Dj_Skual
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * ByteArray.h
 * for SaveGame Manager GX 2012
 ****************************************************************************/
#ifndef _BYTEARRAY_H
#define _BYTEARRAY_H

#include <string>
#include <gctypes.h>

#define SEEK_SET	0
#define SEEK_CUR	1
#define SEEK_END	2

class ByteArray
{
	private:
		u8 *Datas;
		int Size;
		int streamOffset;
		
	public:
		//! Constructs an empty byte array.
		ByteArray();
		//! Constructs an empty byte array of size size.
		ByteArray(int size);
		//! Constructs a copy of the entry byte array.
		ByteArray(const ByteArray &array);
		//! Constructs a byte array containing the first size bytes of array data.
		//! If data is 0, a null byte array is constructed.
		ByteArray(u8 * data, int size);
		//! Constructs a byte array of size str.size()-1 containing str.
		ByteArray(std::string str);
		//! Constructs a byte array of size size with every byte set to character ch.
		ByteArray(int size, char ch);
		//! Destructor
		~ByteArray();
		
		u8& operator[](int index);
		
		operator const char*();
		operator void*();
		
		ByteArray& operator=(const ByteArray &array);
		ByteArray& operator+=(const ByteArray &array);
		ByteArray& operator+=(const u8 &val);
		const ByteArray operator+(const ByteArray &array) const;
		bool operator==(const ByteArray &array);
		bool operator!=(const ByteArray &array);
		
		ByteArray& operator>>(u8 &val);
		ByteArray& operator>>(u16 &val);
		ByteArray& operator>>(u32 &val);
		ByteArray& operator>>(u64 &val);
		ByteArray& operator>>(char &ch);
		ByteArray& operator>>(std::string &str);
		ByteArray& operator>>(ByteArray &array);
		
		ByteArray& operator<<(const u8 &val);
		ByteArray& operator<<(const u16 &val);
		ByteArray& operator<<(const u32 &val);
		ByteArray& operator<<(const u64 &val);
		ByteArray& operator<<(const char ch);
		ByteArray& operator<<(const std::string str);
		ByteArray& operator<<(const ByteArray &array);
		
		u8* data() { return Datas; }
		int size() { return Size; }
		bool empty();
		void clear();
		void realloc(int size);
		void resize(int size);
		void chop(int n);
		const ByteArray left(int size);
		const ByteArray mid(int index, int size = -1);
		const ByteArray right(int size);
		void append(const ByteArray &array);
		void push_back(const ByteArray &array) { append(array); }
		void insert(int index, const ByteArray &array);
		void insert(int index, u8 * data, int size);
		void insert(int index, char ch);
		void prepend(const ByteArray &array) { insert(0, array); }
		void push_front(const ByteArray &array) { insert(0, array); }
		ByteArray& remove(int index, int size);
		
		int seek(int offset, int origin = SEEK_SET);
		void rewind() { streamOffset = 0; }
		int skipRawData(int len);
		bool atEnd();
		int pos() { return streamOffset; }
		
		u16 be16(int index = 0);
		u32 be32(int index = 0);
		u64 be64(int index = 0);
		void wbe16(int index = 0, u16 data = 0);
		void wbe32(int index = 0, u32 data = 0);
		void wbe64(int index = 0, u64 data = 0);
};

ByteArray PaddedByteArray(const ByteArray &array = ByteArray(), int size = 0);

#endif
